#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>
using namespace std;

// 信号量（Semaphore）是一种多线程同步机制，用于管理多线程之间的共享资源访问。
// 通过信号量，可以控制线程进入临界区的数量，保证多线程环境下的资源互斥或同步

// 信号量
sem_t g_sem;

void printer(const char * str)
{
    // P操作，等待信号量
    sem_wait(&g_sem); // 减少信号量的计数，g_sem 减为 0，此时其他线程会被阻塞

    while (*str)
    {
        putchar(*str);
        fflush(stdout);
        str++;

        sleep(1);
    }
    // V操作，释放信号量
    sem_post(&g_sem); // 增加信号量的计数，使 g_sem 的值恢复为 1
}

// 线程 1
void *thread_func1(void *arg)
{
    // 线程分离
    pthread_detach(pthread_self());

    // 线程 tid1 获取锁，输出 "hello" 的五个字符，每输出一个字符休眠 1 秒，总共 5 秒后释放锁。
    const char *str = "hello";
    printer(str);

    // 线程退出
    pthread_exit(NULL);
}

// 线程 2
void *thread_func2(void *arg)
{
    // 线程分离
    pthread_detach(pthread_self());

    // 线程 tid2 获取锁，开始输出 "world" 的五个字符，同样每输出一个字符休眠 1 秒，总共 5 秒后释放锁。
    const char *str = "world";
    printer(str);

    // 线程 tid2 在循环中打印 "I am thread_func2"
    // 因为这部分没有加锁，所以可能与主线程的输出同时进行。
    int count = 10000;
    while (count--)
    {
        cout << "I am thread_func2" << endl;
        sleep(1);
    }

    // 线程退出
    pthread_exit(NULL);
}

int main()
{
    // 初始化信号量
    sem_init(&g_sem, 0, 1);

    pthread_t tid1;
    pthread_create(&tid1, NULL, thread_func1, NULL); 

    pthread_t tid2;
    pthread_create(&tid2, NULL, thread_func2, NULL); 

    // 主线程完成 60 秒倒计时后，直接结束程序
    // 即使线程 2 的循环还没结束，也会被强制终止，因为进程结束时所有关联的线程都会被终止
    // 如果希望主线程在倒计时结束后等待子线程的完成，需要使用 pthread_join 函数
    // 它可以阻塞主线程，直到指定的子线程执行完毕为止。
    int cnt = 60;
    while (cnt--)
    {
        sleep(1);
    }

    // 释放信号量
    sem_destroy(&g_sem);

    return 0;
}